package com.kaching.twitter

sealed abstract class OrderProperties(val name: String, val key: String)

sealed abstract class OrderType(name: String) extends OrderProperties(name, "type")
case class Market() extends OrderType("market-order")
case class Limit(amount: Int) extends OrderType("limit-order")


sealed abstract class OrderAction(name: String) extends OrderProperties(name, "action")
case object Buy extends OrderAction("buy")
case object Sell extends OrderAction("sell")
case object Short extends OrderAction("short")
case object Cover extends OrderAction("cover")

sealed abstract class KcRequest {
  val aliases: Map[String, OrderAction]
  def split(str: String) : Array[String] = str.split("""\$\$""")(0).trim.toLowerCase.split(' ')
  def extractOrderAction(strs: Array[String]) : Option[OrderAction] = {
    for(s <- strs) {
      aliases.get(s) match {
        case Some(a) => return Some(a)
        case _ => //continue
      }
    }
    None
  }
  def extractSymbol(strs: Array[String]) : Option[String] = strs.filter(_.matches("""\$[a-z][a-z0-9\.]*[a-z]""")) match {
    case array if(array.length == 1) => Some(array(0).substring(1).toUpperCase)
    case _ => None
  }
  def extractPrice(strs: Array[String]) : Option[Int] = strs.filter(_.matches("""(@|\$)[0-9]+""")) match {
    case array if(array.length == 1) => Some(array(0).substring(1).toInt)
    case _ => None
  }
  def extractAmount(strs: Array[String]) : Option[Int] = strs.filter(_.matches("""[0-9]+""")) match {
    case array if(array.length == 1) => Some(array(0).toInt)
    case _ => None
  }
  def extractType(strs: Array[String]) = extractPrice(strs) match {
    case None        => Market()
    case Some(price) => Limit(price) 
  }
}

case class KcOrder(action: OrderAction, orderType: OrderType, amount: Int, symbol: String)

case object Order extends KcRequest {
  val aliases = Map("buy" -> Buy, "long" -> Buy, "sell" -> Sell, "short" -> Short, "cover" -> Cover)
  def unapply(str: String) : Option[KcOrder] = {
    val words = split(str)
    extractSymbol(words) match {
      case None         => None
      case Some(symbol) => extractAmount(words) match {
        case None         => None
        case Some(amount) => extractOrderAction(words) match {
          case None         => None
          case Some(action) => Some(KcOrder(action, extractType(words), amount, symbol))
        }
      }
    }
  }
}

